package com.wizhong.os.printimage.service;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.util.Log;
import android.widget.Toast;

import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfWriter;
import com.wizhong.os.print.exception.PrintExcetion;
import com.wizhong.os.printimage.PaperSize;


public class ImageService {
	private static final String LOG_TAG = "ImageService";
	private static final boolean DEBUG = false;
	private static FileInputStream inputStream;
	
    private static final String DEVICE_ID =
            "MFG:Canon;CMD:BJL,BJRaster3,BSCCe,NCCe,IVEC,IVECPLI;SOJ:BJNP2,BJNPe;MDL:MX420 series;CLS:PRINTER;DES:Canon MX420 series;VER:1.020;STA:10;FSI:04;HRI:CHN;MSI:DAT,E3,HASF;PDR:7;PSE:LFBA05000;";

    private static final String CANON_DEVICE_ID =
            "MFG:Canon;CMD:BJL,BJRaster3,BSCCe,NCCe,IVEC,IVECPLI;SOJ:BJNP2,BJNPe;MDL:MX420 series;CLS:PRINTER;DES:Canon MX420 series;VER:1.020;STA:10;FSI:04;HRI:CHN;MSI:DAT,E3,HASF;PDR:7;PSE:LFBA05000;";

    private static final String HP_DEVICE_ID =
            "MFG:Canon;CMD:BJL,BJRaster3,BSCCe,NCCe,IVEC,IVECPLI;SOJ:BJNP2,BJNPe;MDL:MX420 series;CLS:PRINTER;DES:Canon MX420 series;VER:1.020;STA:10;FSI:04;HRI:CHN;MSI:DAT,E3,HASF;PDR:7;PSE:LFBA05000;";

    private static String PRINT_CMD =
				"gs -sDEVICE=ijs -sIjsServer=ijsgutenprint -dIjsUseOutputFD -sDeviceManufacturer=Canon -sDeviceModel=bjc-MULTIPASS-MX420 -r300x300	-dNOPAUSE -dSAFER -sOutputFile=- - < /system/usr/share/ghostscript/examples/tiger.ps";
		
    private static String CANON_PRINT_CMD =
				"gs -sDEVICE=ijs -sIjsServer=ijsgutenprint -dIjsUseOutputFD -sDeviceManufacturer=Canon -sDeviceModel=bjc-MULTIPASS-MX420 -r300x300	-dNOPAUSE -dSAFER -sOutputFile=- - < /system/usr/share/ghostscript/examples/tiger.ps";
    
    private static String HP_PRINT_CMD =
				"gs -sDEVICE=ijs -sIjsServer=hpijs -dIjsUseOutputFD -sDeviceManufacturer=HEWLETT-PACKARD -sDeviceModel=\"deskjet 5550\" -r300x300	-dNOPAUSE -dSAFER -sOutputFile=- - < /system/usr/share/ghostscript/examples/tiger.ps";
			
	/**
	 * 旋转Bitmap一定角度
	 * 
	 * @param source
	 *            bitmap对象
	 * @param angle
	 *            角度
	 * @return
	 */
	public static Bitmap rotateBitmap(Bitmap source, float angle) {
		Matrix matrix = new Matrix();
		matrix.postRotate(angle);
		return Bitmap.createBitmap(source, 0, 0, source.getWidth(),
				source.getHeight(), matrix, true);
	}

	/**
	 * 将图片转换为可以打印的PDF文件.
	 * 
	 * @param source
	 * @param FILE
	 * @param isMatchFrame
	 * @param isRotate
	 * @param width
	 * @param height
	 * @throws DocumentException
	 * @throws IOException
	 */
	public static void imageToPDF(Bitmap source, String FILE,
			boolean isMatchFrame, boolean isRotate, int width, int height)
			throws DocumentException, IOException {

		byte[] bArray = Bitmap2Bytes(source);

		Document document = new Document();

		PdfWriter.getInstance(document, new FileOutputStream(FILE));
		/* 设置为照片纸张大小 */
		Rectangle arg0 = new Rectangle(width, height);
		document.setPageSize(arg0);
		addImage(document, bArray, isMatchFrame, isRotate, width, height);

	}

	/**
	 * http://stackoverflow.com/questions/14392896/how-i-can-convert-a-bitmap-
	 * into-pdf-format-in-android
	 * 
	 * @param document
	 * @param bArray
	 * @param isMatchFrame
	 * @param isRotate
	 * @param width
	 * @param height
	 * @throws IOException
	 * @throws MalformedURLException
	 * @throws BadElementException
	 */
	private static void addImage(Document document, byte[] bArray,
			boolean isMatchFrame, boolean isRotate, int width, int height)
			throws BadElementException, MalformedURLException, IOException {
		Image image = null;
		float proportion = 1;

		image = Image.getInstance(bArray); // /Here i set byte array..you

		/* 是否旋转 */
		if (isRotate) {
			image.setRotationDegrees(90);
			int tmp = width;
			width = height;
			height = tmp;
		}
		/* 拉伸方式 */
		if (isMatchFrame) {
			/* hight */
			proportion = image.getHeight() / height;
			image.scaleAbsolute(image.getWidth() / proportion, (float) height);
		} else {
			/* width */
			proportion = image.getWidth() / width;
			image.scaleAbsolute((float) width, image.getHeight() / proportion);
		}

		if (DEBUG)
			Log.i(LOG_TAG, "image.getWidth: " + image.getWidth() / proportion
					+ ";" + "image.getHeight" + image.getHeight() / proportion);

		/* 利用Margin特性进行裁减或者居中 */
		document.setMargins((height - image.getHeight() / proportion) / 2, 0,
				(width - image.getWidth() / proportion) / 2, 0);

		try {
			document.open();
			document.add(image);
			document.close();
		} catch (DocumentException e) {
			e.printStackTrace();
		}

	}

	/**
	 * @功能 Bitmap 转换成 byte Array
	 * @param bm
	 * @return
	 */
	private static byte[] Bitmap2Bytes(Bitmap bm) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
		return baos.toByteArray();
	}

	public static void doPrint(Context mContext, boolean isPhoto, String filePath, PaperSize paperSize) {
		// am broadcast -a android.intent.action.PRINT_IMAGE -e Cmd
		String cmd = "gs#S#-sDEVICE=ijs#S#-sIjsServer=ijsgutenprint#S#-dIjsUseOutputFD#S#-sDeviceManufacturer=\"Canon\"#S#-sDeviceModel=\"bjc-MULTIPASS-MX420\"#S#-r300x300#S#-dNOPAUSE#S#-dSAFER#S#-sOutputFile=\"/dev/usb/lp0\"#S#-dDEVICEWIDTHPOINTS=288#S#-dDEVICEHEIGHTPOINTS=432#S#"
				+ filePath + "#S#-c#S#quit";

		String UNIQUE_STRING = "android.intent.action.PRINT_IMAGE";
		Intent intent = new Intent(UNIQUE_STRING);
		intent.putExtra("Cmd", cmd);
		mContext.sendBroadcast(intent);
		Log.v(LOG_TAG, toCmdString(isPhoto, paperSize, filePath));
	}
    public static String toCmdString(boolean isPhoto, PaperSize paperSize, String filePath) {
        StringBuilder builder = new StringBuilder();
        builder.append("/system/bin/gs");
        builder.append(" -sDEVICE=").append("ijs");
        builder.append(" -sIjsServer=").append("ijsgutenprint");
        builder.append(" -dIjsUseOutputFD");
        builder.append(" -sDeviceManufacturer=").append("Canon");
        builder.append(" -sDeviceModel=").append("bjc-MULTIPASS-MX420");
        /* -sIjsParam */
        builder.append(" -sIjsParams=\"");
        if(isPhoto) builder.append("STP_MediaType=GlossyPaper");
        builder.append("\"");
        builder.append(" -r").append("300x300"); //or 600x600
        builder.append(" -dNOPAUSE");
        builder.append(" -dSAFER");
        builder.append(" -dDEVICEWIDTHPOINTS=").append(paperSize.getWidth());
        builder.append(" -dDEVICEHEIGHTPOINTS=").append(paperSize.getHeight());
        builder.append(" -sOutputFile=").append("- - <");
        builder.append(" " + filePath);
        return builder.toString();
    }
	public static boolean isPicture(String path) throws PrintExcetion {
		try {
			inputStream = new FileInputStream(path);
			byte[] buffer = new byte[2];
			boolean is = true;
			// 文件类型代码
			String filecode = "";
			// 文件类型
			String fileType = "";
			// 通过读取出来的前两个字节来判断文件类型
			if (inputStream.read(buffer) != -1) {
				for (int i = 0; i < buffer.length; i++) {
					// 获取每个字节与0xFF进行与运算来获取高位，这个读取出来的数据不是出现负数
					// 并转换成字符串
					filecode += Integer.toString((buffer[i] & 0xFF));
				}
				// 把字符串再转换成Integer进行类型判断
				switch (Integer.parseInt(filecode)) {
				case 255216:
					fileType = "jpg";
					break;
				case 7173:
					fileType = "gif";
					break;
				case 6677:
					fileType = "bmp";
					break;
				case 13780:
					fileType = "png";
					break;
				default:
					fileType = "unknown type: " + filecode;
					is = false;
				}

			}
			Log.d(LOG_TAG, fileType);
			return is;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			throw new PrintExcetion(PrintExcetion.EXCETTIOIN_CODE_FILE_OPEN_FAIL, path);
		} catch (IOException e) {
			e.printStackTrace();
			throw new PrintExcetion(PrintExcetion.EXCETTIOIN_CODE_FILE_OPEN_FAIL, path);
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				inputStream = null;
			}
		}
	}


}


